package com.inspur.edp.formserver.viewmodel.util;


import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.designtime.api.collection.GspAssociationCollection;
import com.inspur.edp.cef.designtime.api.collection.GspFieldCollection;
import com.inspur.edp.cef.designtime.api.element.GspAssociation;
import com.inspur.edp.cef.designtime.api.element.GspAssociationKey;
import com.inspur.edp.cef.designtime.api.element.GspElementDataType;
import com.inspur.edp.cef.designtime.api.element.GspEnumValue;
import com.inspur.edp.das.commonmodel.IGspCommonElement;
import com.inspur.edp.das.commonmodel.entity.element.GspCommonAssociation;
import com.inspur.edp.formserver.viewmodel.DotNetToJavaStringHelper;
import com.inspur.edp.formserver.viewmodel.GspViewModelElement;
import com.inspur.edp.udt.designtime.api.entity.ComplexDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.SimpleDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.UnifiedDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.UseTypeInfo;
import com.inspur.edp.udt.designtime.api.entity.dbInfo.ColumnInfo;
import com.inspur.edp.udt.designtime.api.entity.dbInfo.ColumnMapType;
import com.inspur.edp.udt.designtime.api.entity.element.UdtElement;
import com.inspur.edp.udt.designtime.api.entity.enumtype.UseType;
import java.util.UUID;

/**
 更新udt字段
 
*/
public class UpdateVoElementUtil
{
	private boolean isVirtual = true;

	/** 
	 创建字段实例
	 
	 @return 
	*/
	private GspViewModelElement getChildElement()
	{
		GspViewModelElement tempVar = new GspViewModelElement();
		tempVar.setID(UUID.randomUUID().toString());
		return tempVar;
	}

	/** 
	 根据引用的udt元数据更新字段(模板约束均更新)
	 
	 @param element
	 @param udt
	*/
	public final void UpdateElementWithRefUdt(GspViewModelElement element, UnifiedDataTypeDef udt, boolean isFirstChoose)
	{
		element.setUdtID(udt.getId());
		element.setUdtName(udt.getName());



		// 其他属性
		if (udt instanceof ComplexDataTypeDef)
		{
			UpdateComplexDataTypeDefProperties(element, (ComplexDataTypeDef) udt);
		}
		else if (udt instanceof SimpleDataTypeDef )
		{
			UpdateSimpleDataTypeDefProperties(element, (SimpleDataTypeDef) udt, isFirstChoose);
		}
	}

	/** 
	 转换columnInfo为childElement
	 
	 @param info
	 @param prefix
	 @param ele 映射字段
	 @return 
	*/
	public final void MapColumnInfoToField(ColumnInfo info, String prefix, GspViewModelElement ele)
	{
		if (ViewModelUtils.checkNull(prefix))
		{
			throw new RuntimeException("请先完善当前字段的[编号]及[标签]。");
		}
		String  newLabelId = prefix + "_" + info.getCode();
		ele.setLabelID(newLabelId); 
		ele.setCode(newLabelId) ;
		ele.setName(info.getName());
		ele.setMDataType(info.getMDataType());
		ele.setDefaultValue(info.getDefaultValue()); 
		ele.setLength(info.getLength());
		ele.setPrecision(info.getPrecision());
	}

		///#region 单值

	/** 
	 根据单值udt更新字段的其他属性
	 
	 @param element
	 @param sUdt
	 @param isFirstChoose 是否首次选择
	*/
	private void UpdateSimpleDataTypeDefProperties(GspViewModelElement element, SimpleDataTypeDef sUdt, boolean isFirstChoose)
	{
		if (DotNetToJavaStringHelper.isNullOrEmpty(element.getCode()))
		{
			element.setCode(sUdt.getCode()); 
		}
		if (DotNetToJavaStringHelper.isNullOrEmpty(element.getName()))
		{
			element.setName(sUdt.getName());
		}

		if (isFirstChoose || IsConstraint(sUdt, "DataType"))
		{
			element.setMDataType(sUdt.getMDataType()); 
		}
		if (isFirstChoose || IsConstraint(sUdt, "Length"))
		{
			element.setLength(sUdt.getLength());
		}
		if (isFirstChoose || IsConstraint(sUdt, "Precision"))
		{
			element.setPrecision(sUdt.getPrecision()); ;
		}
		if (isFirstChoose || IsConstraint(sUdt, "ObjectType"))
		{
			element.setObjectType(sUdt.getObjectType()); 
			// 关联
			if (element.getChildAssociations() == null)
			{
				element.setChildAssociations( new GspAssociationCollection()) ;
			}

			IGspCommonField belongElement = (element.getChildAssociations() != null && element.getChildAssociations().size() > 0) ? element.getChildAssociations().get(0).getBelongElement() : null;

			GspAssociationCollection assos = element.getChildAssociations().clone(belongElement);

			element.getChildAssociations().clear();
			if (sUdt.getChildAssociations() != null && sUdt.getChildAssociations().size() > 0)
			{
				for (GspAssociation item : sUdt.getChildAssociations())
				{


					GspAssociation beAsso = assos.stream().filter(asso->asso.getId().equals(item.getId())).findFirst().orElse(null);

					element.getChildAssociations().add(ConvertUdtAssociation(item, element, beAsso, isFirstChoose));
				}
			}

			element.setEnumIndexType(sUdt.getEnumIndexType());
			// 枚举
			element.getContainEnumValues().clear();
			if (sUdt.getContainEnumValues() != null && sUdt.getContainEnumValues().size() > 0)
			{
				for (GspEnumValue item : sUdt.getContainEnumValues())
				{
					element.getContainEnumValues().add(item);
				}
			}
		}
		if (isFirstChoose || IsConstraint(sUdt, "DefaultValue"))
		{

			element.setDefaultValue(sUdt.getDefaultValue()==null ? null:sUdt.getDefaultValue().toString());
		}
		if (isFirstChoose || IsConstraint(sUdt, "IsRequired"))
		{
			element.setIsRef(sUdt.getIsRequired());
		}
		// UnifiedDataType属性，前端根据[约束]/[模板]控制属性是否可编辑
		//element.UnifiedDataType = sUdt;
	}

	/** 
	 是否约束
	 
	 @return 
	*/
	private boolean IsConstraint(SimpleDataTypeDef sUdt, String propertyName)
	{
		if (sUdt.getPropertyUseTypeInfos().containsKey(propertyName))
		{

			UseTypeInfo type = sUdt.getPropertyUseTypeInfos().get(propertyName);
			return type.getPropertyUseType() == UseType.AsConstraint;
		}
		else
		{
			throw new RuntimeException("单值业务字段的约束信息中无属性名:"+propertyName);
		}
	}


		///#endregion


		///#region 多值
	/** 
	 根据多值udt更新字段的其他属性
	 
	 @param element
	 @param cUdt
	*/
	private void UpdateComplexDataTypeDefProperties(GspViewModelElement element, ComplexDataTypeDef cUdt)
	{
		if (DotNetToJavaStringHelper.isNullOrEmpty(element.getCode()))
		{
			element.setCode(cUdt.getCode());
		}
		if (DotNetToJavaStringHelper.isNullOrEmpty(element.getName()))
		{
			element.setName(cUdt.getName());
		}

		UdtElement newElement;
		if (cUdt.getElements().size() == 1 && cUdt.getDbInfo().getMappingType() != ColumnMapType.SingleColumn)
		{
			newElement = (UdtElement)((cUdt.getElements().get(0) instanceof UdtElement) ? cUdt.getElements().get(0) : null);
		}
		else
		{
			newElement = new UdtElement(cUdt.getPropertys());
		}

		element.setObjectType(newElement.getObjectType());

		// 若为[单一列]的映射关系，可能导致超长，需把数据类型改为[Text]
		if (cUdt.getDbInfo().getMappingType() == ColumnMapType.SingleColumn)
		{
			element.setMDataType(GspElementDataType.Text);
			element.setLength(0);
			element.setPrecision(0);
		}
		else
		{
			element.setMDataType(newElement.getMDataType());
			element.setLength(newElement.getLength());
			element.setPrecision(newElement.getPrecision());
		}
		element.setDefaultValue(newElement.getDefaultValue());
		element.getChildAssociations().clear();
		element.getContainEnumValues().clear();
	}

		///#endregion


		///#region 关联
	private GspAssociation ConvertUdtAssociation(GspAssociation udtAsso, IGspCommonElement ele, GspAssociation beAsso, boolean isFirstChoose)
	{
		GspCommonAssociation asso = new GspCommonAssociation();
		asso.setId(udtAsso.getId());
		asso.setRefModel((ele.getBelongObject()!=null)?ele.getBelongObject().getBelongModel():null);
		asso.setRefModelCode(udtAsso.getRefModelCode());
		asso.setRefModelID(udtAsso.getRefModelID());
		asso.setRefModelName(udtAsso.getRefModelName());
		asso.setRefModelPkgName(udtAsso.getRefModelPkgName());
		asso.setRefObjectCode(udtAsso.getRefObjectCode());
		asso.setRefObjectID(udtAsso.getRefObjectID());
		asso.setRefObjectName(udtAsso.getRefObjectName());
		if (udtAsso.getKeyCollection().size() > 0)
		{
			for (GspAssociationKey key : udtAsso.getKeyCollection())
			{
				asso.getKeyCollection().add(ConvertUdtAssoKey(key, ele));
			}
		}

		if (isFirstChoose)
		{
			if (udtAsso.getRefElementCollection().size() > 0)
			{
				for (IGspCommonField refEle : udtAsso.getRefElementCollection())
				{
					asso.getRefElementCollection().add(ConvertUdtRefElement((UdtElement)((refEle instanceof UdtElement) ? refEle : null), ele.getLabelID()));
				}
			}
		}
		else
		{
			GspFieldCollection udtRefElements = udtAsso.getRefElementCollection().clone(null, udtAsso);
			// udt带出
			if (beAsso != null && beAsso.getRefElementCollection() != null && beAsso.getRefElementCollection().size() != 0)
			{
				for (IGspCommonField refEle : beAsso.getRefElementCollection())
				{
					if (refEle.getIsFromAssoUdt())
					{
						IGspCommonField refElement=udtRefElements.stream().filter(item->{ return item.getRefElementId().equals(refEle.getRefElementId());}).findFirst().orElse(null);

//						var refElement = udtRefElements.Find(item => item.RefElementId == refEle.RefElementId);
						udtRefElements.remove(refElement);
						// udt仍包含，则加上；udt上已删，则不加。
						if (refElement != null)
						{
							IGspCommonElement refEle2 = ConvertUdtRefElement((UdtElement)((refElement instanceof UdtElement) ? refElement : null), ele.getLabelID());
							refEle2.setID(refEle.getID());
							asso.getRefElementCollection().add(refEle2);
						}
					}
					else
					{
						asso.getRefElementCollection().add(refEle);
					}
				}
			}
			if (udtRefElements.size() > 0)
			{
				for (IGspCommonField refEle : udtRefElements)
				{
					asso.getRefElementCollection().add(ConvertUdtRefElement((UdtElement)((refEle instanceof UdtElement) ? refEle : null), ele.getLabelID()));
				}
			}
		}

		return asso;
	}

	private GspAssociationKey ConvertUdtAssoKey(GspAssociationKey udtKey, IGspCommonElement ele)
	{
		GspAssociationKey key = new GspAssociationKey();
		key.setSourceElement(udtKey.getSourceElement()); 
		key.setSourceElementDisplay(udtKey.getSourceElementDisplay()); 
		key.setTargetElement(ele.getID());
		key.setTargetElementDisplay(ele.getName());
		return key;
	}

	private IGspCommonElement ConvertUdtRefElement(UdtElement udtEle, String prefix)
	{
		GspViewModelElement bizEle = new GspViewModelElement();
		bizEle.setID(udtEle.getID() );
		String newLabelId = prefix + "_" + udtEle.getLabelID();
		bizEle.setLabelID(newLabelId);
		bizEle.setCode(udtEle.getCode());
		bizEle.setName(udtEle.getName());
		bizEle.setMDataType(udtEle.getMDataType());
		bizEle.setObjectType(udtEle.getObjectType());
		bizEle.setLength(udtEle.getLength());
		bizEle.setPrecision(udtEle.getPrecision());
		bizEle.setRefElementId(udtEle.getRefElementId());
		bizEle.setIsRefElement(true);
		bizEle.setIsFromAssoUdt(true);

		// udt相关
		bizEle.setIsUdt(udtEle.getIsUdt());
		bizEle.setUdtID(udtEle.getUdtID());
		bizEle.setUdtName(udtEle.getUdtName());
		bizEle.setUdtPkgName(udtEle.getUdtPkgName());
		switch (udtEle.getObjectType())
		{
			case Enum:
				bizEle.setContainEnumValues(udtEle.getContainEnumValues());
				break;
		}
		// 虚拟vo字段
		if (isVirtual)
		{
			bizEle.setIsVirtualViewElement(true);
			bizEle.setIsVirtual(bizEle.getIsVirtualViewElement());
			bizEle.setMapping(null);
		}
		return bizEle;
	}
		///#endregion
}